package com.gbase8c.dmt.db.metadata;

import com.gbase8c.dmt.model.migration.config.Snapshot;
import com.gbase8c.dmt.model.migration.dto.*;
import org.apache.commons.dbutils.ResultSetHandler;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.List;

public interface Metadata {

    List<String> keywords();

    TransObjDto getTransObjDto();
    UserPrivDto getUserPrivDto();
    List<SchemaDto> getSchemaDtos();

    List<String> getUserNames();
    UserDto getUserDto(String userName);
    UserDto userPriConvert(UserDto userDto);
    String userPrivSql(UserDto userDto) throws SQLException;

    List<String> getRoleNames();
    RoleDto getRoleDto(String roleName);
    RoleDto rolePriConvert(RoleDto roleDto);
    String rolePrivSql(RoleDto roleDto);

    List<String> getSchemaNames();
    List<String> getSchemaNames(boolean includeSystemSchemas);
    SchemaDto getSchemaDto(String schemaName);
    SchemaDto schemaConvert(SchemaDto schemaDto);
    String schemaSql(SchemaDto schemaDto);

    List<String> getTableSpaceNames();
    TableSpaceDto getTableSpaceDto(String tableSpaceName);
    TableSpaceDto tableSpaceConvert(TableSpaceDto tableSpaceDto);
    String tableSpaceSql(TableSpaceDto tableSpaceDto);

    List<String> getTableNames(String schema);
    TableDto getTableDto(String schema, String tableName, List<String> tableSpaceNames);
    TableDto tableConvert(TableDto tableDto);
    List<String> tableSql(TableDto tableDto);
    List<TableTypeMapperDto> tableTypesMapper(String schema);

    BigDecimal dataSize(String schema, String tableName);

    /**
     *
     * @param schema
     * @param type full/include/exclude
     * @param tableNames
     * @return
     */
    List<ColumnType> columnTypes(String schema, String type, List<String> tableNames);
    List<TableDto.ColumnDto> columnDtos(String schema, String tableName);

    List<String> getViewNames(String schema);
    ViewDto getViewDto(String schema, String viewName);
    ViewDto viewConvert(ViewDto viewDto);
    String viewSql(ViewDto viewDto);

    List<String> getFunctionNames(String schema);
    FunctionDto getFunctionDto(String schema, String functionName);
    FunctionDto functionConvert(FunctionDto functionDto, DataSourceDto srcDataSource, DataSourceDto tarDataSource);
    String functionSql(FunctionDto functionDto);

    List<ConstraintDto> getConstraintDtos(String schema);
    List<ConstraintDto> getConstraintDtos(String schema, String table);
    ConstraintDto getConstraintDto(String schema, ConstraintDto constraintDto);
    ConstraintDto constraintConvert(ConstraintDto constraintDto);
    ConstraintDto constraintConvert(ConstraintDto constraintDto,List<String> tableDtoList);
    String constraintSql(ConstraintDto constraintDto);

    List<String> getSequencesNames(String schema);
    List<SequenceDto> getSequencesDtos(String schema);
    SequenceDto getSequenceDto(String schema, String sequenceName);
    SequenceDto sequenceConvert(SequenceDto sequenceDto);
    String sequenceSql(SequenceDto sequenceDto);

    List<String> getSynonymNames(String schema);
    List<SynonymDto> getSynonymDtos(String schema);
    SynonymDto getSynonymDto(String schema, String synonymName);
    SynonymDto synonymConvert(SynonymDto synonymDto);
    String synonynSql(SynonymDto synonymDto);

    List<String> getTriggerNames(String schema);
    TriggerDto getTriggerDto(String schema, String triggerName);
    TriggerDto triggerConvert(TriggerDto triggerDto);
    List<String> triggerSql(TriggerDto triggerDto);

    List<IndexDto> getIndexDtos(String schema);
    List<IndexDto> getIndexDtos(String schema, String table);
    IndexDto getIndexDto(String schema,IndexDto indexDto,List<String> tableSpaceNames);
    IndexDto indexConvert(IndexDto indexDto);
    String indexSql(IndexDto indexDto);

    List<String> getDataTypes();
    Integer toSqlType(String dataType);
    String toDataType(Integer sqlType);
    ColumnType toColumnType(ColumnType srcColumnType);

    String characterSet(String database);

    Snapshot snapshot();

    String wrap(String name, boolean preserveCase);

    <T> T query(String sql, ResultSetHandler<T> rsh, Object... params);
    int execute(String sql, Object... params);

    boolean valid(Snapshot snapshot);
}
